from src.data.channel.los_channel_error_model_no_error import (
    los_channel_error_model_no_error,  # 无误差模型
)
from src.data.channel.los_channel_error_model_multiplicative_on_cos import (
    los_channel_error_model_multiplicative_on_cos,  # 乘法误差模型
)
from src.data.channel.los_channel_error_model_in_sat2user_dist import (
    los_channel_error_model_in_sat2user_dist,  # 卫星到用户距离误差模型
)
from src.data.channel.los_channel_error_model_in_sat_and_user_pos import (
    los_channel_error_model_in_sat_and_user_pos  # 卫星和用户位置误差模型
)


class ConfigErrorModel:
    """
    定义误差模型的参数。
    """

    def __init__(
            self,
    ) -> None:
        """
        初始化配置误差模型的实例。

        初始化时选择默认的误差模型，并调用 update 方法设置相关参数。
        """
        # 选择误差模型
        # self.error_model = los_channel_error_model_no_error
        self.error_model = los_channel_error_model_multiplicative_on_cos
        # self.error_model = los_channel_error_model_in_sat2user_dist
        # self.error_model = los_channel_error_model_in_sat_and_user_pos

        self.update()  # 设置相关参数

    def _set_params(
            self,
    ) -> None:
        """
        根据选择的误差模型设置相关参数。
        """

        # 无误差模型
        # 这是一个虚拟的误差模型，不引入实际的误差
        if self.error_model == los_channel_error_model_no_error:
            self.error_model_name = 'err_no'  # 无误差标识

        # 乘法误差模型
        # 在这种情况下，误差不是直接添加到AOD上，而是均匀分布在cos(AOD)上
        if self.error_model == los_channel_error_model_multiplicative_on_cos:
            self.error_model_name: str = 'err_mult_on_steering_cos'  # 乘法误差标识
            self.uniform_error_interval: dict = {
                'low': -0.0,  # 误差下限
                'high': 0.0,  # 误差上限
            }

        # 卫星到用户距离误差模型
        # 这个误差模型基于扰动的卫星到用户距离估计计算错误的信道状态信息
        if self.error_model == los_channel_error_model_in_sat2user_dist:
            self.error_model_name: str = 'err_sat2userdist'  # 距离误差标识
            self.distance_error_std: float = 0/100_000_000  # 距离误差标准差，例如 1/100,000,000 或 2/100,000,000 等

        # 卫星和用户位置误差模型
        # 该误差模型模拟了卫星之间和用户位置之间的未知相位偏移
        if self.error_model == los_channel_error_model_in_sat_and_user_pos:
            self.error_model_name: str = 'err_satpos_and_userpos'  # 卫星和用户位置误差标识
            self.phase_sat_error_std: float = 0.005  # 卫星相位误差的标准差
            self.uniform_error_interval: dict = {
                'low': -0.1,  # 误差下限
                'high': 0.1,  # 误差上限
            }

        # TODO: 可能需要在AOD上直接添加正态分布误差

    def update(self):
        """
        更新误差模型的参数。
        """
        self._set_params()  # 调用设置参数的方法
